/**to generate database table bean and read/update/delete operation source file
 * by fuzhou huilin corp.ltd @author lms 2016.07.08
 * update by lms 2016.07.09 to remember neboat wind
 * update by lms 2017.05.23 for support get table field info
 * update by lms 2017.12.18 for new code style
 */

package ms.db.mongodb;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ms.core.tool.DateTimeTool;
import ms.core.tool.StrTool;
import ms.core.tool.TemplateTool;

public class MongoCodeHelp {
	private static String tplPath = "/tpl/";
	
	MongoCliDrv db=null;				//数据库连接对象
	String savePath;					//bean、dao、utils 以及 service 父目录完整路径
	Map<String, String> globalVar;		//全局变量
	
	public MongoCodeHelp(String packageName, String savePath){
		try {
			db = MongoCliDrv.getInstance();
			this.savePath= savePath;
			
			globalVar = new HashMap<String, String>();
			globalVar.put("${company}", "Physoon Corp.ltd");
			globalVar.put("${package}", packageName);
			globalVar.put("${author}", System.getenv("USERNAME"));
			globalVar.put("${createDate}", DateTimeTool.dateToDateTimeString(new Date()));
		}catch(Exception e) {}
	}

	public void dispose(){
		if (db!=null) db.close();
		db = null;
	}

	//rule of converting table name to Object name, such as sys_user=>sysUser 
	private String tableToObjectName(String table){
		int i = table.indexOf("_");
		while (i>=0){
			table = StrTool.upperCasePositionTitle(table, i+1);
			table = table.replaceFirst("_", "");
			i = table.indexOf("_");
		}
		return table;
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> getRecord(String collection, String id){
		return db.getRecord(collection, id, Map.class);
	}

////////////////////////////////////////for generate bean code ///////////////////////////////////////////////

	/**
	 * 从集合记录，解析字段及类型
	 * @param table table name of generating bean
	 * @return field declarations text
	 */
	private List<Map<String, String>> getFieldInfo(Map<String, Object> record){
		List<Map<String, String>> rets = new ArrayList<Map<String, String>>();
		try{
			for(Map.Entry<String, Object> e: record.entrySet()) {
				Map<String, String> item = new HashMap<String, String>();
				item.put("${fieldName}", e.getKey());
				item.put("${fieldType}", e.getValue().getClass().getSimpleName());//加入默认

				switch(e.getValue().getClass().getSimpleName()){
				case "Integer":
					item.put("${fieldType}","int");
					break;
				case "Long":
					item.put("${fieldType}","long");
					break;
				default: 
					break;
				}
				rets.add(item);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return rets;
	}

	//to generate table's bean code
	public void makeBean(String collection, Map<String, Object> record){
		String objName = StrTool.upperCaseTitle(tableToObjectName(collection));
		globalVar.put("${objName}", objName);
		globalVar.put("${table}", collection);
		
		List<Map<String, String>> fields = getFieldInfo(record);
		
		String tplFile = tplPath + "mongoBean.tpl";
		String beanFile = savePath+"/bean/"+objName+"Bean.java";
		
		if (TemplateTool.makeFile(tplFile, beanFile, globalVar, fields))
			System.out.println("table "+collection+" bean created!");
		else
			System.out.println("table "+collection+" bean create failure!");
	}
	
//////////////////////////////////////// for generate CRUD code ///////////////////////////////////////////////

//-----------------------------------    generate dao code   ------------------------------------------------
	
	//to generate table's new\modify\delete\query operation
	public void makeDao(String collection, Map<String, Object> record){
		String objName = StrTool.upperCaseTitle(tableToObjectName(collection));
		globalVar.put("${objName}", objName);
		globalVar.put("${table}", collection);

		List<Map<String, String>> fields = getFieldInfo(record);

		String tplFile = tplPath + "mongoDao.tpl";
		String daoFile = savePath+"/dao/"+objName+"Dao.java";
		
		if (TemplateTool.makeFile(tplFile, daoFile, globalVar, fields))
			System.out.println("table "+collection+" dao created!");
		else
			System.out.println("table "+collection+" dao create failure!");
	}

	//-----------------------------------    generate utils code   ------------------------------------------------

	//to make utils
	public void makeUtils(String collection, Map<String, Object> record){
		String objName = StrTool.upperCaseTitle(tableToObjectName(collection));
		globalVar.put("${objName}", objName);
		globalVar.put("${table}", collection);
		
		List<Map<String, String>> fields = getFieldInfo(record);
		
		String tplFile = tplPath + "mongoUtils.tpl";
		String utilsFile = savePath+"/utils/"+objName+"Utils.java";
		
		if (TemplateTool.makeFile(tplFile, utilsFile, globalVar, fields))
			System.out.println("table "+collection+" utils created!");
		else
			System.out.println("table "+collection+" utils create failure!");
	}

	//-----------------------------------    generate service code   ------------------------------------------------

	//to make service
	public void makeService(String collection, Map<String, Object> record){
		String objName = StrTool.upperCaseTitle(tableToObjectName(collection));
		globalVar.put("${objName}", objName);
		globalVar.put("${table}", collection);
		
		List<Map<String, String>> fields = getFieldInfo(record);
		
		String tplFile = tplPath + "mongoService.tpl";
		String serviceFile = savePath+"/service/"+objName+"Service.java";
		
		if (TemplateTool.makeFile(tplFile, serviceFile, globalVar, fields))
			System.out.println("table "+collection+" service created!");
		else
			System.out.println("table "+collection+" service create failure!");
	}
	
	public static void main(String[] args){
		MongoCodeHelp hlp = new MongoCodeHelp("hs.com","d://tmp");
		String collection = "sp_campaigns";
		String id = "620f311940ef2c04f7f9da71";
		Map<String, Object> record = hlp.getRecord(collection, id);

		hlp.makeBean(collection, record);
		//hlp.makeDao("sys_role");
		//hlp.makeUtils("sys_role");
		//hlp.makeService("sys_role");
		//List<Field> list = hlp.getTableField("sys_role");
		//System.out.println(JsonTool.listBeanToJson(list));
		hlp.dispose();
	}
}
